package com.unlcn.ils.wms.backend.service.borrow.impl;

import cn.huiyunche.commons.exception.BusinessException;
import cn.huiyunche.commons.utils.QiniuUtil;

import com.unlcn.ils.wms.backend.enums.DeleteFlagEnum;
import com.unlcn.ils.wms.backend.enums.InboundOrderBusinessTypeEnum;
import com.unlcn.ils.wms.backend.enums.TmsInspectStatusEnum;
import com.unlcn.ils.wms.backend.enums.WmsInspectExcpTypeEnum;
import com.unlcn.ils.wms.backend.service.borrow.WmsReturnCarService;
import com.unlcn.ils.wms.base.dto.BorrowDetailDTO;
import com.unlcn.ils.wms.base.dto.ReturnCarLineDTO;
import com.unlcn.ils.wms.base.dto.ReturnDetailDTO;
import com.unlcn.ils.wms.base.mapper.additional.WmsInboundAsnOrderAddMapper;
import com.unlcn.ils.wms.base.mapper.additional.WmsInventoryLocationExtMapper;
import com.unlcn.ils.wms.base.mapper.extmapper.WmsBorrowCarDetailExtMapper;
import com.unlcn.ils.wms.base.mapper.extmapper.WmsOutOfStorageExtMapper;
import com.unlcn.ils.wms.base.mapper.extmapper.WmsReturnCarExtMapper;
import com.unlcn.ils.wms.base.mapper.inspectApp.TmsInspectExcpTypeMapper;
import com.unlcn.ils.wms.base.mapper.stock.WmsBorrowCarMapper;
import com.unlcn.ils.wms.base.mapper.stock.WmsReturnCarMapper;
import com.unlcn.ils.wms.base.model.inbound.WmsInboundOrder;
import com.unlcn.ils.wms.base.model.inspectApp.TmsInspectExcpType;
import com.unlcn.ils.wms.base.model.junmadcs.WmsOutOfStorage;
import com.unlcn.ils.wms.base.model.stock.WmsBorrowCar;
import com.unlcn.ils.wms.base.model.stock.WmsBorrowCarDetail;
import com.unlcn.ils.wms.base.model.stock.WmsInventoryLocation;
import com.unlcn.ils.wms.base.model.stock.WmsReturnCar;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by lenovo on 2017/10/20.
 */
@Service
public class WmsReturnCarServiceImpl implements WmsReturnCarService {

    @Autowired
    private WmsReturnCarMapper wmsReturnCarMapper;

    @Autowired
    private WmsReturnCarExtMapper wmsReturnCarExtMapper;

    @Autowired
    private WmsBorrowCarMapper wmsBorrowCarMapper;

    @Autowired
    private WmsBorrowCarDetailExtMapper wmsBorrowCarDetailExtMapper;

    @Autowired
    private WmsInventoryLocationExtMapper wmsInventoryLocationExtMapper;

    @Autowired
    private WmsOutOfStorageExtMapper wmsOutOfStorageExtMapper;
    
    @Autowired
    private WmsInboundAsnOrderAddMapper inboundAsnOrderAddMapper;

    @Autowired
    private TmsInspectExcpTypeMapper tmsInspectExcpTypeMapper;
    
    @Override
    public Integer returnLineCount(Map<String, Object> paramsMap) {
        return wmsReturnCarExtMapper.returnLineCount(paramsMap);
    }

    @Override
    public List<ReturnCarLineDTO> returnLine(Map<String, Object> paramsMap) {
    	
    	List<ReturnCarLineDTO> returnCarLineList = wmsReturnCarExtMapper.returnLine(paramsMap);
    	
    	// 获取上传凭证的url
        for (ReturnCarLineDTO returnCarLineDTO : returnCarLineList) {
        	if(StringUtils.isNotBlank(returnCarLineDTO.getUploadKey())) {
        		String downloadURL = QiniuUtil.generateDownloadURL(returnCarLineDTO.getUploadKey(), "");
                returnCarLineDTO.setUploadPath(downloadURL);
        	}
        }
        return wmsReturnCarExtMapper.returnLine(paramsMap);
    }

    @Override
    public List<WmsBorrowCarDetail> findReturnDetail(Long returnId) {
        Map<String, Object> paramsMap = new HashMap<String, Object>();
        paramsMap.put("bdReturnId", returnId);
        return wmsBorrowCarDetailExtMapper.findParams(paramsMap);
    }

    @Override
    public void add(WmsReturnCar wmsReturnCar, List<WmsBorrowCarDetail> wmsBorrowCarDetailList) {
        if (!StringUtils.isEmpty(wmsReturnCar.getRcBorrowNo())) {
            // 查找借用车辆信息
            Map<String, Object> paramsMap = new HashMap<String, Object>();
            paramsMap.put("bdReturnStatus", 10);
            paramsMap.put("rcBorrowNo", wmsReturnCar.getRcBorrowNo());
            List<WmsBorrowCarDetail> wmsBorrowCarDetails = wmsBorrowCarDetailExtMapper.findParams(paramsMap);
            if (CollectionUtils.isEmpty(wmsBorrowCarDetails))
                throw new BusinessException("找不到借车单未归还车辆信息!");

            for (WmsBorrowCarDetail wmsBorrowCarDetail : wmsBorrowCarDetails) {
                // 查询车辆是否已经出库
                Map<String, Object> params = new HashMap<String, Object>();
                params.put("zaction", "C1");
                params.put("ztype", "Z7");
                params.put("serialNo", wmsReturnCar.getRcBorrowNo());
                params.put("sernr", wmsBorrowCarDetail.getBdVin());
                List<WmsOutOfStorage> wmsOutOfStorageList =  wmsOutOfStorageExtMapper.findByParams(params);
                if (CollectionUtils.isEmpty(wmsOutOfStorageList))
                    throw new BusinessException("车架号" + wmsBorrowCarDetail.getBdVin() + "的车辆还未出库");
                
                //查询入库单中的车辆数据是否已经验车
                Map<String,Object> map = new HashMap<>();
                map.put("businessType", InboundOrderBusinessTypeEnum.Z8.getCode());
                map.put("isDelect", DeleteFlagEnum.NORMAL.getValue());
                map.put("vin", wmsBorrowCarDetail.getBdVin());
                WmsInboundOrder inboundOrder = inboundAsnOrderAddMapper.selectInboundOrderByVin(map);
                if(null == inboundOrder) {
                	throw new BusinessException("未找到该车入库信息");
                }
                
                //不是 合格 与 验车完成
                if(inboundOrder.getInspectStatus() != TmsInspectStatusEnum.WAYBILL_QUALIFY.getValue() && inboundOrder.getInspectStatus() != TmsInspectStatusEnum.WAYBILL_CONFIRM_EXCP.getValue()) {
                	throw new BusinessException(wmsBorrowCarDetail.getBdVin() + "车辆未验车合格");
                }
                
                //如果是验车完成 
                if(inboundOrder.getInspectStatus() == TmsInspectStatusEnum.WAYBILL_CONFIRM_EXCP.getValue()) {
                	//需要查看验车登记异常
                	TmsInspectExcpType inspectExcpType = tmsInspectExcpTypeMapper.selectByPrimaryKey(inboundOrder.getOdInspectExcpType().intValue());
                	if(!WmsInspectExcpTypeEnum.TYPE_MISS.getCode().equals(inspectExcpType.getTypeCode())) {
                		throw new BusinessException(wmsBorrowCarDetail.getBdVin() + "车辆未验车合格");
                	}
                }
            }

            // 新增借车单
            wmsReturnCar.setGmtCreate(new Date());
            wmsReturnCarMapper.insertSelective(wmsReturnCar);
            WmsReturnCar updateReturnNo = new WmsReturnCar();
            SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
            Integer maxId = wmsReturnCarExtMapper.selectMaxId();
            updateReturnNo.setRcReturnNo("HC" + formatter.format(new Date()) + maxId);
            updateReturnNo.setRcReturnDate(new Date());
            updateReturnNo.setGmtUpdate(new Date());
            updateReturnNo.setRcId(wmsReturnCar.getRcId());
            wmsReturnCarMapper.updateByPrimaryKeySelective(updateReturnNo);

            // 更新被借用的车辆状态为已归还
            wmsBorrowCarDetailExtMapper.updateStatusByBorrowNo(wmsReturnCar.getRcId(), wmsReturnCar.getRcBorrowNo());
        } else {
            // 校验交还的车辆信息是否正确
            List<String> borrowNos = new ArrayList<String>();
            for (WmsBorrowCarDetail wmsBorrowCarDetail : wmsBorrowCarDetailList) {
                Map<String, Object> paramsMap = new HashMap<String, Object>();
                paramsMap.put("bdVin", wmsBorrowCarDetail.getBdVin());
                paramsMap.put("bdReturnStatus", 10);
                List<WmsBorrowCarDetail> wmsBorrowCarDetails = wmsBorrowCarDetailExtMapper.findParams(paramsMap);
                // 如果不是借出的车辆，则生成不了还车单
                if (CollectionUtils.isEmpty(wmsBorrowCarDetails))
                    throw new BusinessException("车架号" + wmsBorrowCarDetail.getBdVin() + "不是借出的车辆");

                // 查询车架号对应的借车单
                Long borrowId = wmsBorrowCarDetails.get(0).getBdBorrowId();
                WmsBorrowCar wmsBorrow = wmsBorrowCarMapper.selectByPrimaryKey(borrowId);
                if (wmsBorrow == null)
                    throw new BusinessException("车架号" + wmsBorrowCarDetail.getBdVin() + "找不到借车单");

                // 查询车辆是否已经出库
                Map<String, Object> params = new HashMap<String, Object>();
                params.put("zaction", "C1");
                params.put("ztype", "Z7");
                params.put("serialNo", wmsBorrow.getBcBorrowNo());
                params.put("sernr", wmsBorrowCarDetail.getBdVin());
                List<WmsOutOfStorage> wmsOutOfStorageList =  wmsOutOfStorageExtMapper.findByParams(params);
                if (CollectionUtils.isEmpty(wmsOutOfStorageList))
                    throw new BusinessException("车架号" + wmsBorrowCarDetail.getBdVin() + "的车辆还未出库");

                //查询入库单中的车辆数据是否已经验车
                Map<String,Object> map = new HashMap<>();
                map.put("businessType", InboundOrderBusinessTypeEnum.Z8.getCode());
                map.put("isDelect", DeleteFlagEnum.NORMAL.getValue());
                map.put("vin", wmsBorrowCarDetail.getBdVin());
                WmsInboundOrder inboundOrder = inboundAsnOrderAddMapper.selectInboundOrderByVin(map);
                
                //不是 合格 与 验车完成
                if(inboundOrder.getInspectStatus() != TmsInspectStatusEnum.WAYBILL_QUALIFY.getValue() && inboundOrder.getInspectStatus() != TmsInspectStatusEnum.WAYBILL_CONFIRM_EXCP.getValue()) {
                	throw new BusinessException(wmsBorrowCarDetail.getBdVin() + "车辆未验车合格");
                }
                
                //如果是验车完成 
                if(inboundOrder.getInspectStatus() == TmsInspectStatusEnum.WAYBILL_CONFIRM_EXCP.getValue()) {
                	//需要查看验车登记异常
                	TmsInspectExcpType inspectExcpType = tmsInspectExcpTypeMapper.selectByPrimaryKey(inboundOrder.getOdInspectExcpType().intValue());
                	if(inspectExcpType.getTypeCode() != WmsInspectExcpTypeEnum.TYPE_EXCP.getCode()) {
                		throw new BusinessException(wmsBorrowCarDetail.getBdVin() + "车辆未验车合格");
                	}
                }
                
                borrowNos.add(wmsBorrow.getBcBorrowNo());
            }

            // 校验还车的车辆是否都属于同一个借车单的车辆
            String borrowNo = borrowNos.get(0);
            for (String no : borrowNos) {
                if (!borrowNo.equals(no)) {
                    throw new BusinessException("所还车辆不是属于同一个借车单的!");
                }
            }

            // set 还车单的借车单号
            wmsReturnCar.setRcBorrowNo(borrowNo);
            // 新增借车单
            wmsReturnCar.setGmtCreate(new Date());
            wmsReturnCarMapper.insertSelective(wmsReturnCar);
            WmsReturnCar updateReturnNo = new WmsReturnCar();
            updateReturnNo.setRcReturnNo("RR" + wmsReturnCar.getRcId());
            updateReturnNo.setRcReturnDate(new Date());
            updateReturnNo.setGmtUpdate(new Date());
            updateReturnNo.setRcId(wmsReturnCar.getRcId());
            wmsReturnCarMapper.updateByPrimaryKeySelective(updateReturnNo);

            // 更新被借用的车辆状态为已归还
            List<String> bdVins = new ArrayList<String>();
            for (WmsBorrowCarDetail wmsBorrowCarDetail : wmsBorrowCarDetailList) {
                bdVins.add(wmsBorrowCarDetail.getBdVin());
            }
            wmsBorrowCarDetailExtMapper.updateStatusByVin(wmsReturnCar.getRcId(), bdVins);
        }
    }

    @Override
    public List<ReturnDetailDTO> queryModifyDetail(Long rcId) {
    	
    	List<ReturnDetailDTO> returnDetailList = wmsReturnCarExtMapper.queryReturnDetail(rcId);
    	
    	// 获取上传凭证的url
        for (ReturnDetailDTO returnDetailDTO : returnDetailList) {
        	if(StringUtils.isNotBlank(returnDetailDTO.getUploadKey())) {
        		String downloadURL = QiniuUtil.generateDownloadURL(returnDetailDTO.getUploadKey(), "");
                returnDetailDTO.setUploadPath(downloadURL);
        	}
        }
        return returnDetailList;
    }

    @Override
    public void modify(WmsReturnCar wmsReturnCar, List<WmsBorrowCarDetail> wmsBorrowCarDetailList) {
        // 校验是否借用车辆是否已经出库
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("deleteFlag", 1);
        params.put("bdReturnId", wmsReturnCar.getRcId());
        List<WmsBorrowCarDetail> borrowCarDetailList =  wmsBorrowCarDetailExtMapper.findParams(params);
        for (WmsBorrowCarDetail detail : borrowCarDetailList) {
            params = new HashMap<String, Object>();
            params.put("isDeleted", 1);
            params.put("invlocVin", detail.getBdVin());
            List<WmsInventoryLocation> wmsInventoryLocationList = wmsInventoryLocationExtMapper.findParams(params);
            if (!CollectionUtils.isEmpty(wmsInventoryLocationList))
                throw new BusinessException("还车单已经入库，不能编辑");
        }

        wmsReturnCarMapper.updateByPrimaryKeySelective(wmsReturnCar);

        Map<String, Object> paramsMap = new HashMap<String, Object>();
        paramsMap.put("deleteFlag", 1);
        paramsMap.put("bdReturnId", wmsReturnCar.getRcId());
        List<WmsBorrowCarDetail> details = wmsBorrowCarDetailExtMapper.findParams(paramsMap);

        // 判断编辑是否有删除还车明细
        for (WmsBorrowCarDetail detail : details) {
            if (detail.getBdReturnStatus() == 20) {
                Boolean have = true;
                for (WmsBorrowCarDetail detail1 : wmsBorrowCarDetailList) {
                    if (detail1.getBdId()!=null && detail1.getBdId()==detail1.getBdId()) {
                        have = false;
                        break;
                    }
                }

                // 如果存在删除的还车明细，则还原车辆为未还车状态
                if (have == false) {
                    // 清除车辆状态未为归还
                    wmsBorrowCarDetailExtMapper.clearReturn(null, detail.getBdVin());
                }
            }
        }

        // 判断编辑是否有增加的还车明细
        List<String> bdVins = new ArrayList<String>();
        for (WmsBorrowCarDetail detail : wmsBorrowCarDetailList) {
            if (detail == null) {
                Map<String, Object> paramsMap2 = new HashMap<String, Object>();
                paramsMap2.put("bdVin", detail.getBdVin());
                paramsMap2.put("bdReturnStatus", 10);
                List<WmsBorrowCarDetail> wmsBorrowCarDetails = wmsBorrowCarDetailExtMapper.findParams(paramsMap);
                // 如果不是借出的车辆，则生成不了还车单
                if (CollectionUtils.isEmpty(wmsBorrowCarDetails))
                    throw new BusinessException("车架号" + detail.getBdVin() + "不是借出的车辆");
                
                //查询入库单中的车辆数据是否已经验车
                Map<String,Object> map = new HashMap<>();
                map.put("businessType", InboundOrderBusinessTypeEnum.Z8.getCode());
                map.put("isDelect", DeleteFlagEnum.NORMAL.getValue());
                map.put("vin", detail.getBdVin());
                WmsInboundOrder inboundOrder = inboundAsnOrderAddMapper.selectInboundOrderByVin(map);
                
                //不是 合格 与 验车完成
                if(inboundOrder.getInspectStatus() != TmsInspectStatusEnum.WAYBILL_QUALIFY.getValue() && inboundOrder.getInspectStatus() != TmsInspectStatusEnum.WAYBILL_CONFIRM_EXCP.getValue()) {
                	throw new BusinessException(detail.getBdVin() + "车辆未验车合格");
                }
                
                //如果是验车完成 
                if(inboundOrder.getInspectStatus() == TmsInspectStatusEnum.WAYBILL_CONFIRM_EXCP.getValue()) {
                	//需要查看验车登记异常
                	TmsInspectExcpType inspectExcpType = tmsInspectExcpTypeMapper.selectByPrimaryKey(inboundOrder.getOdInspectExcpType().intValue());
                	if(inspectExcpType.getTypeCode() != WmsInspectExcpTypeEnum.TYPE_EXCP.getCode()) {
                		throw new BusinessException(detail.getBdVin() + "车辆未验车合格");
                	}
                }
                
                bdVins.add(detail.getBdVin());
            }
        }
        if (!CollectionUtils.isEmpty(bdVins)) {
            // 更新新添加的明细为已经还车状态
            wmsBorrowCarDetailExtMapper.updateStatusByVin(wmsReturnCar.getRcId(), bdVins);
        }
    }

    @Override
    public void delete(List<Long> rcIds) {
        for (Long rcId : rcIds) {
            // 校验是否借用车辆是否已经出库
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("deleteFlag", 1);
            params.put("bdReturnId", rcId);
            List<WmsBorrowCarDetail> borrowCarDetailList =  wmsBorrowCarDetailExtMapper.findParams(params);
            for (WmsBorrowCarDetail detail : borrowCarDetailList) {
                params = new HashMap<String, Object>();
                params.put("isDeleted", 1);
                params.put("invlocVin", detail.getBdVin());
                List<WmsInventoryLocation> wmsInventoryLocationList = wmsInventoryLocationExtMapper.findParams(params);
                if (!CollectionUtils.isEmpty(wmsInventoryLocationList))
                    throw new BusinessException("还车单已经入库，不能删除");
            }
        }

        // 删除还车单
        wmsReturnCarExtMapper.deleteReturn(rcIds);
        // 清除车辆状态未为归还
        wmsBorrowCarDetailExtMapper.clearReturn(rcIds, null);
    }

    @Override
    public List<WmsBorrowCarDetail> getDetail(String borrowNo) {
        Map<String, Object> paramsMap = new HashMap<String, Object>();
        paramsMap.put("deleteFlag", 1);
        paramsMap.put("rcBorrowNo", borrowNo);
        return wmsBorrowCarDetailExtMapper.findParams(paramsMap);
    }
}
